package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.MessageConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.*;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.*;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Autowired
    private DishService dishService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private CategoryService categoryService;

    /**
     * 分页查询套餐数据
     * @param pageQueryDTO
     * @return
     */
    @Override
    public PageResult page(SetmealPageQueryDTO pageQueryDTO){
        Page<Setmeal> pageInfo = new Page<>(
                pageQueryDTO.getPage(),
                pageQueryDTO.getPageSize()
        );
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(
                StringUtils.isNotEmpty(pageQueryDTO.getName()),
                Setmeal::getName,
                pageQueryDTO.getName()
        );
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);
        super.page(pageInfo,queryWrapper);
        // VO
        List<SetmealVO> setmealVOList = pageInfo.getRecords().stream().map(item->{
            SetmealVO setmealVO = new SetmealVO();
            BeanUtils.copyProperties(item, setmealVO);
            // 查询分类信息
            Category category = categoryService.getById(item.getId());
            if (category != null){
                setmealVO.setCategoryName(category.getName());
            }
            // 查询关联菜品数据
            LambdaQueryWrapper<SetmealDish> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(SetmealDish::getSetmealId, item.getId());
            setmealVO.setSetmealDishes(setmealDishService.list(queryWrapper1));
            return setmealVO;
        }).collect(Collectors.toList());
        // 构造数据
        PageResult pageResult = new PageResult(
                pageInfo.getTotal(),
                setmealVOList
        );
        return pageResult;
    }

    /**
     * 保存套餐信息
     * @param setmealDTO
     * @return
     */
    @Transactional
    @Override
    public void save(SetmealDTO setmealDTO){
        // 1 保存基本信息
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal,"setmealDishes");
        super.save(setmeal);
        // 2 保存关联的菜品信息
        List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes().stream().map(item -> {
            item.setSetmealId(setmeal.getId());
            return item;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishList);
    }

    /**
     * 根据Id 查询套餐
     * @return
     */
    @Override
    public SetmealVO getById(Long id){
        SetmealVO setmealVO = new SetmealVO();
        Setmeal setmeal = super.getById(id);
        BeanUtils.copyProperties(setmeal, setmealVO);
        // 获取关联菜品信息
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, setmeal.getId());
        setmealVO.setSetmealDishes(setmealDishService.list());
        return  setmealVO;
    }

    /**
     * 根据Id 批量删除
     * @param ids
     */
    @Transactional
    @Override
    public void  removeByIds(List<Long> ids){
        // 校验
        // 1 起售套餐  不允许删除
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId, ids);
        queryWrapper.eq(Setmeal::getStatus, 1);
        long count = super.count(queryWrapper);
        if (count > 0){
            throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
        }

        // 1 删除基本信息
        super.removeByIds(ids);

        // 2 删除关联菜品信息
        LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishLambdaQueryWrapper.in(SetmealDish::getSetmealId, ids);
        setmealDishService.remove(setmealDishLambdaQueryWrapper);
    }

    /**
     * 修改套餐数据
     * @param setmealDTO
     */
    @Override
    @Transactional
    public void  updateById(SetmealDTO setmealDTO){
        // 1 删除关联菜品
        LambdaQueryWrapper<SetmealDish> dishFlavorQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorQueryWrapper.eq(SetmealDish::getSetmealId, setmealDTO.getId());
        setmealDishService.remove(dishFlavorQueryWrapper);
        // 2 修改基本信息
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal, "setmealDishes");
        super.updateById(setmeal);
        // 2 添加关联菜品
        List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes().stream().map(item -> {
            item.setSetmealId(setmeal.getId());
            return item;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishList);
    }

    /**
     * 更新套餐起售，停售
     * @param status
     * @param id
     */
    @Override
    public void updateStatus( Integer status, Long id ){
        Setmeal setmeal = super.getById(id);
        setmeal.setStatus(status);
        super.updateById(setmeal);
    }


    /**
     * 根据id查询菜品选项
     * @param id
     * @return
     */
    @Override
    public List<DishItemVO> getDishItemById(Long id){
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);
        //
        List<DishItemVO> dishItemVOList  = setmealDishes.stream().map(item -> {
            DishItemVO dishItemVO = new DishItemVO();
            DishVO dishVO = dishService.getById(item.getDishId());
            if (dishVO!=null){
                dishItemVO.setName(dishVO.getName());
                dishItemVO.setDescription(dishVO.getDescription());
                dishItemVO.setCopies(item.getCopies());
                dishItemVO.setImage(dishVO.getImage());
            }
            return dishItemVO;
        }).collect(Collectors.toList());
        return  dishItemVOList ;
    }
}
